﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input.Touch;
using System.IO.IsolatedStorage;

namespace Oiler
{
    public partial class GamePage : PhoneApplicationPage
    {
        UIElementRenderer elementRenderer;
        ContentManager Content;
        GameTimer timer;
        SpriteBatch spriteBatch;
        SpriteFont GameFont;
        IsolatedStorageSettings saveGame;

        public OilDeposits[] depos;
        public int realTime;
        bool canAdjust;
        Vector2 pos;
        
        SDGraph supply = new SDGraph();
        SDGraph demand = new SDGraph();
        MapControl map = new MapControl();
        Player player = new Player();
        OilDeposits selectedOil;
        Date date = new Date();
        Vector2 selectPos = new Vector2(150, 190);
        Employees employ = new Employees();

        public bool isGameRunning;

        public GamePage()
        {
            InitializeComponent();
            LayoutUpdated += new EventHandler(GamePage_LayoutUpdated);

            // Get the content manager from the application
            Content = (Application.Current as App).Content;

            // Create a timer for this page
            timer = new GameTimer();
            timer.UpdateInterval = TimeSpan.FromTicks(333333);
            timer.Update += OnUpdate;
            timer.Draw += OnDraw;

            depos = new OilDeposits[3];

            depos[0] = new OilDeposits(65000, .15, false, "Alaska", 0);
            depos[1] = new OilDeposits(95000, .1, true, "Gulf Coast", 1);
            depos[2] = new OilDeposits(250000, 0.02, false, "Middle East", 2);

            saveGame = IsolatedStorageSettings.ApplicationSettings;

            player.Load(saveGame);
            date.Load(saveGame);
            for (int i = 0; i < depos.Length; i++)
            {
                depos[i].Load(saveGame);
            }
        }

        void GamePage_LayoutUpdated(object sender, EventArgs e)
        {
            // Create the UIElementRenderer to draw the XAML page to a texture.

            // Check for 0 because when we navigate away the LayoutUpdate event
            // is raised but ActualWidth and ActualHeight will be 0 in that case.
            if ((ActualWidth > 0) && (ActualHeight > 0))
            {
                SharedGraphicsDeviceManager.Current.PreferredBackBufferWidth = (int)ActualWidth;
                SharedGraphicsDeviceManager.Current.PreferredBackBufferHeight = (int)ActualHeight;
            }

            if (null == elementRenderer)
            {
                elementRenderer = new UIElementRenderer(this, (int)ActualHeight, (int)ActualWidth);
            }
        }


        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            // Set the sharing mode of the graphics device to turn on XNA rendering
            SharedGraphicsDeviceManager.Current.GraphicsDevice.SetSharingMode(true);

            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(SharedGraphicsDeviceManager.Current.GraphicsDevice);

            isGameRunning = true;

            /*
             * Object Array for Oil Deposits
             * 1 = Alaska
             * 2 = Gulf
             * 3 = Middle Eas
             */

            // TODO: use this.content to load your game content here
            map.Initialize(Content.Load<Texture2D>("Map"), Content.Load<Texture2D>("Dot"));

            //initialize supply and demand bar graph, apply texture, and set positions.
            demand.Initialize(Content.Load<Texture2D>("Fill"), pos = new Vector2(745, 25));
            supply.Initialize(Content.Load<Texture2D>("Fill"), pos = new Vector2(703, 25));
            player.Initialize(saveGame);
            date.Initialize(saveGame);
            

            for (int i = 0; i < depos.Length; i++)
            {
                depos[i].Initialize(Content.Load<Texture2D>("StatsPanel"), Content.Load<Texture2D>("Dot"));
            }

            GameFont = Content.Load<SpriteFont>("GameFont");

            // Start the timer
            timer.Start();

            base.OnNavigatedTo(e);
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            // Stop the timer
            timer.Stop();
            isGameRunning = false;

            player.Save(saveGame);
            date.Save(saveGame);
            for (int i = 0; i < depos.Length; i++)
            {
                depos[i].Save(saveGame);
            }

            // Set the sharing mode of the graphics device to turn off XNA rendering
            SharedGraphicsDeviceManager.Current.GraphicsDevice.SetSharingMode(false);

            base.OnNavigatedFrom(e);
        }

        /// <summary>
        /// Allows the page to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        private void OnUpdate(object sender, GameTimerEventArgs e)
        {
            // TODO: Add your update logic here
            
            //UPDATE OIL SELECTION
            //targets chosen oil well
            if (map.canMove)
            {
                HandleSelection();
            }


            //UPDATE EMPLOYEE MODEL
            employ.Update();


            //UPDATE MAP/VIEW
            //updates the maps position and changes overall
            //view of the map and its objects placed on it
            map.Update(e);


            //UPDATE PLAYER
            //updates the players income and expenses based
            //on a calcualation over time
            player.Update(depos, realTime, isGameRunning, saveGame, date, MoneyCut);


            //REALTIME
            //self created timer for more accurate results
            if (isGameRunning)
            {
                realTime = e.TotalTime.Seconds;
            }

            
            //UPDATE DATE
            //updates day, month, and year based [[1 second == 2 days]]
            date.Update(isGameRunning);


            //ZOOM CONTROLS
            //zooms in and out based on a button press from user
            //ZOOM OUT
            if (button2.IsPressed)
            {
                map.ZoomOut();
            }
            //ZOOM IN
            if (button1.IsPressed)
            {
                map.ZoomIn();
            }


            //UPDATE OIL DEPOSITS
            //updates each deposit via for loop based on  
            //the number of created deposits
            for (int i = 0; i < depos.Length; i++)
            {
                depos[i].Update(map.depositPos[i], map, saveGame, isGameRunning, player);
            }


            //UPDATE SUPPLY DEMAND GRAPH
            supply.Update(player, 0);
            demand.Update(player, 1);


            //XAML CONTROLS
            #region xamlcontrols

            //MONEY/DATE DISPLAY
            //updates the games running date and
            //the players money ammount to later
            //be drawn in the OnDraw method
            textBlock2.Text = String.Format("{0:C}",player.PlayerMoney);
            textBlock3.Text = ((int)date.Day).ToString() + "/" + date.Month.ToString() + "/" + date.Year.ToString();
            textBlock4.Text = (int)player.WorldAcceptance/2 + "%";
            if (player.teleRun)
                TeleRunning.Text = "Running";
            else
                TeleRunning.Text = "Not Running";
            if (player.radRun)
                RadRunning.Text = "Running";
            else
                RadRunning.Text = "Not Running";
            if (player.newsRun)
                NewsRunning.Text = "Running";
            else
                NewsRunning.Text = "Not Running";
            if (player.billRun)
                BillRunning.Text = "Running";
            else
                BillRunning.Text = "Not Running";

            textBlock5.Text = player.adCanRun.ToString();
            textBlock6.Text = player.adBoost.ToString();
            if ((int)MoneyCut.Value != 0)
            {
                CutOff.Text = String.Format("Cut Off: {0:C}", MoneyCut.Value);
            }
            else
                CutOff.Text = "Run Ad Indefinitely!";
            MoneyCut.Maximum = player.PlayerMoney;
            textBlock9.Text = player.BarrelPrice.ToString();
            PriceButton.Content = player.BarrelPrice.ToString();
            textBlock11.Text = player.Supply.ToString();
            textBlock12.Text = player.Demand.ToString();
            textBlock13.Text = player.tempIncome.ToString();
            if (selectedOil != null)
            {
                textBlock14.Text = selectedOil.arrPos.ToString();
            }

            if (StatsPlate.Visibility == Visibility.Visible || PriceCanvas.Visibility == Visibility.Visible)
            {
                map.canMove = false;
            }
            else
            {
                map.canMove = true;
            }

            #endregion endxamlcontrols

        }

        /// <summary>
        /// Allows the page to draw itself.
        /// </summary>
        private void OnDraw(object sender, GameTimerEventArgs e)
        {
            SharedGraphicsDeviceManager.Current.GraphicsDevice.Clear(Color.CornflowerBlue);
            
            // TODO: Add your drawing code here
            elementRenderer.Render();

            spriteBatch.Begin();
            map.Draw(spriteBatch, GameFont);
            
            
            for (int i = 0; i < depos.Length; i++)
            {
                depos[i].Draw(spriteBatch, GameFont, map.depositPos[i], map);
            }
            spriteBatch.Draw(elementRenderer.Texture, Vector2.Zero, Color.White);

            //draws supply bar and demand bar.
            demand.Draw(spriteBatch);
            supply.Draw(spriteBatch);

            employ.Draw(spriteBatch, GameFont, EmployeeCanvas);

            spriteBatch.End();
            
        }



        public void HandleSelection()
        {
            TouchCollection touches = TouchPanel.GetState();

            if (touches.Count > 0 && touches[0].State == TouchLocationState.Pressed)
            {
                Microsoft.Xna.Framework.Point p = new Microsoft.Xna.Framework.Point((int)touches[0].Position.X, (int)touches[0].Position.Y);

                for (int i = 0; i < depos.Length; i++)
                {
                    if (depos[i].HitBounds.Contains(p))
                    {
                        selectedOil = depos[i];
                        canAdjust = true;
                        canvas4.Visibility = Visibility.Visible;
                        break;
                    }
                }
            }
            if (canAdjust == true && selectedOil.HitBounds.Center.X > selectPos.X ||
                canAdjust == true && selectedOil.HitBounds.Center.X < selectPos.X)
            {
                map.MapPosition.X -= (selectedOil.HitBounds.Center.X - selectPos.X) / 2;
                canvas4.Visibility = Visibility.Visible;

                if (selectedOil.HitBounds.Center.X < selectPos.X + 15 && selectedOil.HitBounds.Center.X > selectPos.X - 10 &&
                    selectedOil.HitBounds.Center.Y < selectPos.Y + 15 && selectedOil.HitBounds.Center.Y > selectPos.Y - 10)
                {
                    canAdjust = false;
                    StatsPlate.Visibility = Visibility.Visible;
                }
            }
            if (canAdjust == true && selectedOil.HitBounds.Center.Y > selectPos.Y ||
                canAdjust == true && selectedOil.HitBounds.Center.Y < selectPos.Y)
            {
                map.MapPosition.Y -= (selectedOil.HitBounds.Center.Y - selectPos.Y) / 2;
            }
            if (canAdjust && map.mapScale < 2)
            {
                map.mapScale += .25f;
            }
            
        }

        //
        //
        //
        //WINDOWS PHONE CONTROLS REGION
        //
        //
        //

        #region WindowPhoneControls

        //PAUSE/START BUTTON
        //flips a boolean that paused on the updates
        //throughout the games variables
        private void PauseGame(object sender, RoutedEventArgs e)
        {
            if (isGameRunning)
            {
                isGameRunning = false;
                button7.Content = "Start";
            }
            else
            {
                isGameRunning = true;
                button7.Content = "Pause";
            }
        }


        //BUILD RIGS
        //buttons provided for user input to create
        //their oil rigs on selected well
        private void BuildSmallRig(object sender, RoutedEventArgs e)
        {
            if (selectedOil != null && player.PlayerMoney >= selectedOil.lowOilRigCost && selectedOil.isUsable)
            {
                selectedOil.LowerOilRigs = 1;
                player.PlayerMoney = -selectedOil.lowOilRigCost;
            }
        }
        private void BuildMedRig(object sender, RoutedEventArgs e)
        {
            if (selectedOil != null && player.PlayerMoney >= selectedOil.medOilRigCost && selectedOil.isUsable)
            {
                selectedOil.MedOilRigs = 1;
                player.PlayerMoney = -selectedOil.medOilRigCost;
            }
        }
        private void BuildHighRig(object sender, RoutedEventArgs e)
        {
            if (selectedOil != null && player.PlayerMoney >= selectedOil.highOilRigCost && selectedOil.isUsable)
            {
                selectedOil.HighOilRigs = 1;
                player.PlayerMoney = -selectedOil.highOilRigCost;
            }
        }


        //BUILD MENU
        //provides pop up menu for the build buttons
        private void add(object sender, RoutedEventArgs e)
        {
            if (canvas4.Visibility == Visibility.Collapsed)
            {
                canvas4.Visibility = Visibility.Visible;
            }
            else
            {
                canvas4.Visibility = Visibility.Collapsed;
            }
        }

        private void OpenMarket(object sender, RoutedEventArgs e)
        {
            if (MarketCanvas.Visibility == Visibility.Collapsed)
            {
                MarketCanvas.Visibility = Visibility.Visible;
            }
            else
                MarketCanvas.Visibility = Visibility.Collapsed;
        }

        //AD MODIFICATIONS
        //user selects ad and these numbers
        //modify the effectivness of the ad
        private void TeleSelect(object sender, RoutedEventArgs e)
        {
            player.teleSelect = true;
            player.radSelect = false;
            player.newsSelect = false;
            player.billSelect = false;
            if (player.teleRun)
                StartAd.Content = "Stop";
            else
                StartAd.Content = "Run";
        }
        private void RadSelect(object sender, RoutedEventArgs e)
        {
            player.teleSelect = false;
            player.radSelect = true;
            player.newsSelect = false;
            player.billSelect = false;
            if (player.radRun)
                StartAd.Content = "Stop";
            else
                StartAd.Content = "Run";
        }
        private void NewsSelect(object sender, RoutedEventArgs e)
        {
            player.teleSelect = false;
            player.radSelect = false;
            player.newsSelect = true;
            player.billSelect = false;
            if (player.newsRun)
                StartAd.Content = "Stop";
            else
                StartAd.Content = "Run";
        }
        private void BillSelect(object sender, RoutedEventArgs e)
        {
            player.teleSelect = false;
            player.radSelect = false;
            player.newsSelect = false;
            player.billSelect = true;
            if (player.billRun)
                StartAd.Content = "Stop";
            else
                StartAd.Content = "Run";
        }
        private void ConfrimAd(object sender, RoutedEventArgs e)
        {
            if (player.teleSelect)
            {
                if (!player.teleRun)
                {
                    player.teleRun = true;
                    player.adBoost += 50;
                }
                else
                {
                    player.teleRun = false;
                    player.adBoost -= 50;
                }
            }
            if (player.radSelect)
            {
                if (!player.radRun)
                {
                    player.radRun = true;
                    player.adBoost += 25;
                }
                else
                {
                    player.radRun = false;
                    player.adBoost -= 25;
                }
            }
            if (player.newsSelect)
            {
                if (!player.newsRun)
                {
                    player.newsRun = true;
                    player.adBoost += 20;
                }
                else
                {
                    player.newsRun = false;
                    player.adBoost -= 20;
                }
            }
            if (player.billSelect)
            {
                if (!player.billRun)
                {
                    player.billRun = true;
                    player.adBoost += 5;
                }
                else
                {
                    player.billRun = false;
                    player.adBoost -= 5;
                }
            }

            StartAd.Content = "Stop";
            if (!player.teleRun && !player.radRun && !player.billRun && !player.newsRun)
            {
                player.adCanRun = false;
            }
            else
            {
                player.adCanRun = true;
            }
            player.adChange = true;
        }        
        
        private void SetPrice(object sender, RoutedEventArgs e)
        {
            if (PriceCanvas.Visibility == Visibility.Visible)
                PriceCanvas.Visibility = Visibility.Collapsed;
            else
                PriceCanvas.Visibility = Visibility.Visible;

            button8.Visibility = Visibility.Visible;
            button8.IsHitTestVisible = true;
        }
        private void UpPrice(object sender, RoutedEventArgs e)
        {
            player.BarrelPrice = 1;
        }
        private void DownPrice(object sender, RoutedEventArgs e)
        {
            player.BarrelPrice = -1;
        }
        private void ClosePrice(object sender, RoutedEventArgs e)
        {
            PriceCanvas.Visibility = Visibility.Collapsed;
            button8.Visibility = Visibility.Collapsed;
            button8.IsHitTestVisible = false;
            map.canMove = true;
        }

        private void CloseStats(object sender, RoutedEventArgs e)
        {
            StatsPlate.Visibility = Visibility.Collapsed;
            map.canMove = true;
        }

        private void EmployButton_Click(object sender, RoutedEventArgs e)
        {
            if (EmployeeCanvas.Visibility == Visibility.Collapsed)
            {
                EmployeeCanvas.Visibility = Visibility.Visible;
            }
            else
                EmployeeCanvas.Visibility = Visibility.Collapsed;
        }

        #endregion





    }
}